package msgcenter

import (
	"context"
	"sync"

	"gitee.com/doraemon1996/bunny/protocol"
)

// 消息上下文结构
// 实现消息处理过程中的流程中断、参数穿透、超时机制等
type msgContext struct {
	ctx context.Context

	// 消息源数据
	data *protocol.Message

	// 参数穿透
	value any

	// 响应通道 传递[]byte或error
	resChan chan<- any
	resOnce *sync.Once
}

// 消息上下文
func newContext(ctx context.Context, msg *protocol.Message, resChan chan<- any) *msgContext {
	msgCtx := new(msgContext)
	msgCtx.ctx = ctx
	msgCtx.data = msg
	msgCtx.resChan = resChan
	if resChan != nil {
		msgCtx.resOnce = new(sync.Once)
	}
	return msgCtx
}

// 获取上下文
func (ctx *msgContext) Context() context.Context {
	return ctx.ctx
}

// 判断消息处理过程是否应当终止
func (ctx *msgContext) Closed() bool {
	select {
	case <-ctx.ctx.Done():
		return true
	default:
		return false
	}
}

// 服务消息简略信息
func (ctx *msgContext) String() string {
	if ctx.data != nil {
		return ctx.data.String()
	} else {
		return "empty message"
	}
}

// 获取消息数据
func (ctx *msgContext) Data() *protocol.Message {
	return ctx.data
}

// 设置参数
func (ctx *msgContext) SetValue(val any) {
	ctx.value = val
}

// 获取参数
func (ctx *msgContext) GetValue() any {
	return ctx.value
}

// 响应源服务的Call
func (ctx *msgContext) Response(data []byte) {
	if ctx.Closed() {
		return
	}

	if ctx.resOnce != nil {
		ctx.resOnce.Do(func() {
			ctx.resChan <- data
		})
	}
}

// 响应源服务的Call
func (ctx *msgContext) Error(err error) {
	if ctx.Closed() {
		return
	}

	if ctx.resOnce != nil {
		ctx.resOnce.Do(func() {
			ctx.resChan <- err
		})
	}
}
